package vn.com.hung.notetaker.mis.forms;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.GroupLayout;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.common.io.Closeables;
import com.google.common.io.Files;

import vn.com.hung.notetaker.datatypes.MisTags;
import vn.com.hung.notetaker.mis.datamodels.NoteLine;
import vn.com.hung.notetaker.mis.menus.MiscPopupMenu;
import vn.com.hung.notetaker.utils.DialogDisplayer;
import vn.com.hung.notetaker.utils.SpecialChars;

@SuppressWarnings("serial")
public class MiscPanel extends JPanel {
    
    
    private ArrayList<NoteLine> lines = new ArrayList<NoteLine>();
    private MyMouseListener listener = new MyMouseListener();
    private String path = null;
    private int selectedRow = -1;
    private GroupLayout layout;
    private ParallelGroup pg;
    private SequentialGroup sg;
    
    public MiscPanel(int row) {
        layout = new GroupLayout(this);
        this.setLayout(layout);
        pg = layout.createParallelGroup(Alignment.LEADING);
        sg = layout.createSequentialGroup();
        
        for (int i = 0; i < row; i++) {
            NoteLine line = new NoteLine();
            line.addMouseListener(listener);
            line.setName("" + i);
            lines.add(line);
            pg.addComponent(line);
            sg.addComponent(line);
        }
        layout.setHorizontalGroup(pg);
        layout.setVerticalGroup(sg);
    }
    
    public void addLines(int count) {
        int row = lines.size();
        for (int i = 0; i < count; i++) {
            NoteLine line = new NoteLine();
            line.setName("" + (row + i));
            lines.add(line);
            pg.addComponent(line);
            sg.addComponent(line);
        }
        layout.setHorizontalGroup(pg);
        layout.setVerticalGroup(sg);
    }
    
    public NoteLine getLine(int i) {
        return lines.get(i);
    }
    
    public int getSelectedRow() {
        return selectedRow; 
    }
    
    public void load(File file) {
        // remember path for automatic saving
        path = file.getAbsolutePath();
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(file);
            doc.getDocumentElement().normalize();
            NodeList noteList = doc.getElementsByTagName(MisTags.PAGE_TAG);
            if (noteList.getLength() > lines.size()) {
                addLines(noteList.getLength() - lines.size());
            } 
            Iterator<NoteLine> it = lines.iterator();
            for (int i = 0; i < noteList.getLength(); i++) {
                Node node = noteList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    System.out.println(i);
                    Element elem = (Element) node;
                    NoteLine line = it.next();
                    line.setText(getValue(MisTags.CONTENT_TAG, elem));
                    line.setTags(getValue(MisTags.TAGS_TAG,elem));
                    line.setLink(getValue(MisTags.LINK_TAG, elem));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            DialogDisplayer.showDefaultErrorDialog("Invalid Input File!");
        }
        
    }
    
    public void saveXML(String path) {
     // remember path for automatic saving
        this.path = path;
        BufferedWriter writer = null;
        try {
            writer = Files.newWriter(new File(path), Charset.forName("UTF-8"));
            writer.write(MisTags.ROOT_TAG_START + "\n");
            for (NoteLine line : lines) {
                if (line.getText().length() < 2) {
                    continue;
                }
                writer.write(MisTags.PAGE_TAG_START); 
                writer.write(MisTags.CONTENT_TAG_START);
                writer.write(SpecialChars.regularize(line.getText()));
                writer.write(MisTags.CONTENT_TAG_END + "\n");
                writer.write(MisTags.TAGS_TAG_START);
                writer.write(line.getTags());
                writer.write(MisTags.TAGS_TAG_END + "\n");
                writer.write(MisTags.LINK_TAG_START);
                writer.write(SpecialChars.regularize(line.getLink()));
                writer.write(MisTags.LINK_TAG_END + "\n");
                writer.write(MisTags.PAGE_TAG_END);
                
            }
            writer.write(MisTags.ROOT_TAG_END + "\n");
            
        } catch(IOException e) {
            
        } finally {
            Closeables.closeQuietly(writer);
        }
    }
    public void saveContextXML() {
        // automatic saving
        if (path == null) {
            DialogDisplayer.showDefaultErrorDialog("Cannot Save. Path has not set");
        } else {
            saveXML(path);
            DialogDisplayer.showDefaultInforDialog("Save Done!");
        }
    }
    
    
    private String getValue(String tag, Element elem) {
        NodeList nodes = elem.getElementsByTagName(tag).item(0).getChildNodes();
        Node node = (Node) nodes.item(0);
        return node.getNodeValue();
    }
    
    private class MyMouseListener extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            NoteLine area = (NoteLine) e.getComponent();
            int rowClicked = Integer.parseInt(area.getName());
            if (SwingUtilities.isLeftMouseButton(e)) {
                if (selectedRow != rowClicked && selectedRow != -1) {
                    getLine(selectedRow).setBackground(Color.white);
                }
                selectedRow = rowClicked;
                area.setBackground(Color.yellow);
            } else if (SwingUtilities.isRightMouseButton(e)) {
                Point p = e.getPoint();
                if (rowClicked == selectedRow) {
                    MiscPopupMenu menu = new MiscPopupMenu(getLine(rowClicked));
                    menu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        }
        
    }

}
